import babel.messages.pofile
import base64
import datetime
import functools
import glob
import hashlib
import imghdr
import io
import itertools
import jinja2
import json
import logging
import operator
import os
import re
import sys
import tempfile
import time
import zlib

import werkzeug
import werkzeug.exceptions
import werkzeug.utils
import werkzeug.wrappers
import werkzeug.wsgi
from collections import OrderedDict
from werkzeug.urls import url_decode, iri_to_uri
from xml.etree import ElementTree
import unicodedata


import odoo
import odoo.modules.registry
from odoo.api import call_kw, Environment
from odoo.modules import get_resource_path
from odoo.tools import crop_image, topological_sort, html_escape, pycompat
from odoo.tools.mimetypes import guess_mimetype
from odoo.tools.translate import _
from odoo.tools.misc import str2bool, xlwt, file_open
from odoo.tools.safe_eval import safe_eval
from odoo import http
from odoo.http import content_disposition, dispatch_rpc, request, \
    serialize_exception as _serialize_exception, Response
from odoo.exceptions import AccessError, UserError, AccessDenied
from odoo.models import check_method_name
from odoo.service import db, security

_logger = logging.getLogger(__name__)

if hasattr(sys, 'frozen'):
    pass
else:
    loader = jinja2.PackageLoader('odoo.addons.web', "views")

env = jinja2.Environment(loader=loader, autoescape=True)
env.filters["json"] = json.dumps

# 1 week cache for asset bundles as advised by Google Page Speed
BUNDLE_MAXAGE = 60 * 60 * 24 * 7

DBNAME_PATTERN = '^[a-zA-Z0-9][a-zA-Z0-9_.-]+$'

db_list = http.db_list

db_monodb = http.db_monodb

def clean(name): return name.replace('\x3c', '')
def serialize_exception(f):
    @functools.wraps(f)
    def wrap(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except Exception as e:
            _logger.exception("An exception occured during an http request")
            se = _serialize_exception(e)
            error = {
                'code': 200,
                'message': "Odoo Server Error",
                'data': se
            }
            return werkzeug.exceptions.InternalServerError(json.dumps(error))
    return wrap

def redirect_with_hash(*args, **kw):
    pass

def abort_and_redirect(url):
    pass

def ensure_db(redirect='/web/database/selector'):
    pass

def module_installed(environment):
    pass

def module_installed_bypass_session(dbname):
    pass

def module_boot(db=None):
    pass

def concat_xml(file_list):
    pass

def fs2web(path):
    pass

def manifest_glob(extension, addons=None, db=None, include_remotes=False):
    pass

def manifest_list(extension, mods=None, db=None, debug=None):
    pass

def get_last_modified(files):
    pass

def make_conditional(response, last_modified=None, etag=None, max_age=0):
    pass

def login_and_redirect(db, login, key, redirect_url='/web'):
    pass

def set_cookie_and_redirect(redirect_url):
    pass

def clean_action(action):
    pass

def generate_views(action):
    pass

def fix_view_modes(action):
    pass

def _local_web_translations(trans_file):
    pass

def xml2json_from_elementtree(el, preserve_whitespaces=False):
    pass

def binary_content(xmlid=None, model='ir.attachment', id=None, field='datas', unique=False,
                   filename=None, filename_field='datas_fname', download=False, mimetype=None,
                   default_mimetype='application/octet-stream', related_id=None, access_mode=None, access_token=None,
                   env=None):
    return request.registry['ir.http'].binary_content(
        xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename,
        filename_field=filename_field, download=download, mimetype=mimetype,
        default_mimetype=default_mimetype, related_id=related_id, access_mode=access_mode, access_token=access_token,
        env=env)

class Home(http.Controller):
    @http.route('/', type='http', auth="none")
    def index(self, s_action=None, db=None, **kw):
        pass

    @http.route('/web', type='http', auth="none")
    def web_client(self, s_action=None, **kw):
        pass

    @http.route('/web/dbredirect', type='http', auth="none")
    def web_db_redirect(self, redirect='/', **kw):
        pass

    def _login_redirect(self, uid, redirect=None):
        pass

    @http.route('/web/login', type='http', auth="none", sitemap=False)
    def web_login(self, redirect=None, **kw):
        pass

    @http.route('/web/become', type='http', auth='user', sitemap=False)
    def switch_to_admin(self):
        pass

class WebClient(http.Controller):
    @http.route('/web/webclient/csslist', type='json', auth="none")
    def csslist(self, mods=None):
        pass

    @http.route('/web/webclient/jslist', type='json', auth="none")
    def jslist(self, mods=None):
        pass

    @http.route('/web/webclient/locale/<string:lang>', type='http', auth="none")
    def load_locale(self, lang):
        pass

    @http.route('/web/webclient/qweb', type='http', auth="none", cors="*")
    def qweb(self, mods=None, db=None):
        pass

    @http.route('/web/webclient/bootstrap_translations', type='json', auth="none")
    def bootstrap_translations(self, mods):
        pass

    @http.route('/web/webclient/translations', type='json', auth="none")
    def translations(self, mods=None, lang=None):
        pass

    @http.route('/web/tests', type='http', auth="user")
    def test_suite(self, mod=None, **kwargs):
        pass

    @http.route('/web/tests/mobile', type='http', auth="none")
    def test_mobile_suite(self, mod=None, **kwargs):
        pass

    @http.route('/web/benchmarks', type='http', auth="none")
    def benchmarks(self, mod=None, **kwargs):
        pass

class Proxy(http.Controller):

    @http.route('/web/proxy/load', type='json', auth="none")
    def load(self, path):
        pass

    @http.route('/web/proxy/post/<path:path>', type='http', auth='user', methods=['GET'])
    def post(self, path):
        pass


class Database(http.Controller):

    def _render_template(self, **d):
        d.setdefault('manage',True)
        d['insecure'] = odoo.tools.config.verify_admin_password('admin')
        d['list_db'] = odoo.tools.config['list_db']
        d['langs'] = odoo.service.db.exp_list_lang()
        d['countries'] = odoo.service.db.exp_list_countries()
        d['pattern'] = DBNAME_PATTERN
        # databases list
        d['databases'] = []
        try:
            d['databases'] = http.db_list()
            d['incompatible_databases'] = odoo.service.db.list_db_incompatible(d['databases'])
        except odoo.exceptions.AccessDenied:
            monodb = db_monodb()
            if monodb:
                d['databases'] = [monodb]
        return env.get_template("database_manager.html").render(d)

    @http.route('/web/database/selector', type='http', auth="none")
    def selector(self, **kw):
        request._cr = None
        return self._render_template(manage=False)

    @http.route('/web/database/manager', type='http', auth="none")
    def manager(self, **kw):
        pass

    @http.route('/web/database/create', type='http', auth="none", methods=['POST'], csrf=False)
    def create(self, master_pwd, name, lang, password, **post):
        pass

    @http.route('/web/database/duplicate', type='http', auth="none", methods=['POST'], csrf=False)
    def duplicate(self, master_pwd, name, new_name):
        pass

    @http.route('/web/database/drop', type='http', auth="none", methods=['POST'], csrf=False)
    def drop(self, master_pwd, name):
        pass

    @http.route('/web/database/backup', type='http', auth="none", methods=['POST'], csrf=False)
    def backup(self, master_pwd, name, backup_format='zip'):
        pass

    @http.route('/web/database/restore', type='http', auth="none", methods=['POST'], csrf=False)
    def restore(self, master_pwd, backup_file, name, copy=False):
        pass

    @http.route('/web/database/change_password', type='http', auth="none", methods=['POST'], csrf=False)
    def change_password(self, master_pwd, master_pwd_new):
        pass

    @http.route('/web/database/list', type='json', auth='none')
    def list(self):
        pass

class Session(http.Controller):

    @http.route('/web/session/get_session_info', type='json', auth="none")
    def get_session_info(self):
        pass

    @http.route('/web/session/authenticate', type='json', auth="none")
    def authenticate(self, db, login, password, base_location=None):
        pass

    @http.route('/web/session/change_password', type='json', auth="user")
    def change_password(self, fields):
        pass

    @http.route('/web/session/get_lang_list', type='json', auth="none")
    def get_lang_list(self):
        pass

    @http.route('/web/session/modules', type='json', auth="user")
    def modules(self):
        pass

    @http.route('/web/session/save_session_action', type='json', auth="user")
    def save_session_action(self, the_action):
        pass

    @http.route('/web/session/get_session_action', type='json', auth="user")
    def get_session_action(self, key):
        pass

    @http.route('/web/session/check', type='json', auth="user")
    def check(self):
        pass

    @http.route('/web/session/account', type='json', auth="user")
    def account(self):
        pass

    @http.route('/web/session/destroy', type='json', auth="user")
    def destroy(self):
        pass

    @http.route('/web/session/logout', type='http', auth="none")
    def logout(self, redirect='/web'):
        pass

class DataSet(http.Controller):

    @http.route('/web/dataset/search_read', type='json', auth="user")
    def search_read(self, model, fields=False, offset=0, limit=False, domain=None, sort=None):
        pass

    def do_search_read(self, model, fields=False, offset=0, limit=False, domain=None
                       , sort=None):
        pass

    @http.route('/web/dataset/load', type='json', auth="user")
    def load(self, model, id, fields):
        pass

    def call_common(self, model, method, args, domain_id=None, context_id=None):
        pass

    def _call_kw(self, model, method, args, kwargs):
        pass

    @http.route('/web/dataset/call', type='json', auth="user")
    def call(self, model, method, args, domain_id=None, context_id=None):
        pass

    @http.route(['/web/dataset/call_kw', '/web/dataset/call_kw/<path:path>'], type='json', auth="user")
    def call_kw(self, model, method, args, kwargs, path=None):
        pass

    @http.route('/web/dataset/call_button', type='json', auth="user")
    def call_button(self, model, method, args, domain_id=None, context_id=None):
        pass

    @http.route('/web/dataset/resequence', type='json', auth="user")
    def resequence(self, model, ids, field='sequence', offset=0):
        pass

class View(http.Controller):

    @http.route('/web/view/edit_custom', type='json', auth="user")
    def edit_custom(self, custom_id, arch):
        pass

class Binary(http.Controller):

    def placeholder(self, image='placeholder.png'):
        pass

    def force_contenttype(self, headers, contenttype='image/png'):
        pass

    @http.route(['/web/content',
         '/web/content/<string:xmlid>',
         '/web/content/<string:xmlid>/<string:filename>',
         '/web/content/<int:id>',
         '/web/content/<int:id>/<string:filename>',
         '/web/content/<int:id>-<string:unique>',
         '/web/content/<int:id>-<string:unique>/<string:filename>',
         '/web/content/<int:id>-<string:unique>/<path:extra>/<string:filename>',
         '/web/content/<string:model>/<int:id>/<string:field>',
         '/web/content/<string:model>/<int:id>/<string:field>/<string:filename>'], type='http', auth="public")
    def content_common(self, xmlid=None, model='ir.attachment', id=None, field='datas',
                       filename=None, filename_field='datas_fname', unique=None, mimetype=None,
                       download=None, data=None, token=None, access_token=None, related_id=None, access_mode=None,
                       **kw):
        pass

    @http.route(['/web/image',
        '/web/image/<string:xmlid>',
        '/web/image/<string:xmlid>/<string:filename>',
        '/web/image/<string:xmlid>/<int:width>x<int:height>',
        '/web/image/<string:xmlid>/<int:width>x<int:height>/<string:filename>',
        '/web/image/<string:model>/<int:id>/<string:field>',
        '/web/image/<string:model>/<int:id>/<string:field>/<string:filename>',
        '/web/image/<string:model>/<int:id>/<string:field>/<int:width>x<int:height>',
        '/web/image/<string:model>/<int:id>/<string:field>/<int:width>x<int:height>/<string:filename>',
        '/web/image/<int:id>',
        '/web/image/<int:id>/<string:filename>',
        '/web/image/<int:id>/<int:width>x<int:height>',
        '/web/image/<int:id>/<int:width>x<int:height>/<string:filename>',
        '/web/image/<int:id>-<string:unique>',
        '/web/image/<int:id>-<string:unique>/<string:filename>',
        '/web/image/<int:id>-<string:unique>/<int:width>x<int:height>',
        '/web/image/<int:id>-<string:unique>/<int:width>x<int:height>/<string:filename>'], type='http',auth="public")
    def content_image(self, xmlid=None, model='ir.attachment', id=None, field='datas',
                      filename_field='datas_fname', unique=None, filename=None, mimetype=None,
                      download=None, width=0, height=0, crop=False, related_id=None, access_mode=None,
                      access_token=None, avoid_if_small=False, upper_limit=False, signature=False, **kw):
        pass

    @http.route(['/web/binary/image'], type='http', auth="public")
    def content_image_backward_compatibility(self, model, id, field, resize=None, **kw):
        pass

    @http.route('/web/binary/upload', type='http', auth="user")
    @serialize_exception
    def upload(self, callback, ufile):
        pass

    @http.route('/web/binary/upload_attachment', type='http', auth="user")
    @serialize_exception
    def upload_attachment(self, callback, model, id, ufile):
        pass

    @http.route([
        '/web/binary/company_logo',
        '/logo',
        '/logo.png',
    ], type='http', auth="none", cors="*")
    def company_logo(self, dbname=None, **kw):
        pass

class Action(http.Controller):

    @http.route('/web/action/load', type='json', auth="user")
    def load(self, action_id, additional_context=None):
        pass

    @http.route('/web/action/run', type='json', auth="user")
    def run(self, action_id):
        pass

class Export(http.Controller):

    @http.route('/web/export/formats', type='json', auth="user")
    def formats(self):
        pass

    def fields_get(self, model):
        pass

    @http.route('/web/export/get_fields', type='json', auth="user")
    def get_fields(self, model, prefix='', parent_name='',
                   import_compat=True, parent_field_type=None,
                   parent_field=None, exclude=None):
        pass

    @http.route('/web/export/namelist', type='json', auth="user")
    def namelist(self, model, export_id):
        pass

    def graft_subfields(self, model, prefix, prefix_string, fields):
        pass

class ExportFormat(object):
    raw_data = False
    max_rows = None

    @property
    def content_type(self):
        pass

    def filename(self, base):
        pass

    def from_data(self, fields, rows):
        pass

    def base(self, data, token):
        pass

class CSVExport(ExportFormat, http.Controller):

    @http.route('/web/export/csv', type='http', auth="user")
    @serialize_exception
    def index(self, data, token):
        pass

    @property
    def content_type(self):
        pass

    def filename(self, base):
        pass

    def from_data(self, fields, rows):
        pass

class ExcelExport(ExportFormat, http.Controller):
    # Excel needs raw data to correctly handle numbers and date values
    raw_data = True
    max_rows = 65535

    @http.route('/web/export/xls', type='http', auth="user")
    @serialize_exception
    def index(self, data, token):
        pass

    @property
    def content_type(self):
        pass

    def filename(self, base):
        pass

    def from_data(self, fields, rows):
        pass

class Apps(http.Controller):
    @http.route('/apps/<app>', auth='user')
    def get_app_url(self, req, app):
        pass

class ReportController(http.Controller):
    @http.route([
        '/report/<converter>/<reportname>',
        '/report/<converter>/<reportname>/<docids>',
    ], type='http', auth='user', website=True)
    def report_routes(self, reportname, docids=None, converter=None, **data):
        pass

    @http.route(['/report/barcode', '/report/barcode/<type>/<path:value>'], type='http', auth="public")
    def report_barcode(self, type, value, width=600, height=100, humanreadable=0):
        pass

    @http.route(['/report/download'], type='http', auth="user")
    def report_download(self, data, token):
        pass

    @http.route(['/report/check_wkhtmltopdf'], type='json', auth="user")
    def check_wkhtmltopdf(self):
        pass



